﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace DDD.Extensions;

public static class JwtAuthenticationExtension
{

    /// <summary>
    /// JWT 验证
    /// </summary>
    /// <param name="services"></param>
    /// <param name="jwtSchemeOption"></param>
    /// <returns></returns>
    public static IServiceCollection AddDefaultJwt(this IServiceCollection services, JwtSchemeOption jwtSchemeOption)
    {
        services.AddAuthentication(op =>
        {
            op.DefaultAuthenticateScheme = jwtSchemeOption.Scheme;
        })
        .AddJwtBearer(jwtSchemeOption.Scheme, op =>
        {
            op.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
            {
                ValidateIssuer = true,
                ValidIssuer = jwtSchemeOption.Issure,
                ValidateAudience = true,
                ValidAudience = jwtSchemeOption.Audiance,
                ValidateLifetime = true,
                RequireExpirationTime = true,
                ClockSkew = TimeSpan.Zero,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSchemeOption.Serect))
            };

            op.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents()
            {
                OnMessageReceived = context =>
                {
                    var tokenQuery = context.HttpContext.Request.Query.FirstOrDefault();
                    if (!string.IsNullOrEmpty(tokenQuery.Key))
                    {
                        context.HttpContext.Request.Headers.Add("Authorization", $"Bearer {tokenQuery.Value}");
                    }

                    return Task.CompletedTask;
                },
            };
        });

        return services;
    }
}

public sealed record JwtSchemeOption
{
    public string Scheme { get; init; }

    public string Issure { get; init; }

    public string Audiance { get; init; }

    public string Serect { get; init; }
}
